/*
**************************************************************************************************************
*                                          通讯处理
*
*  描 述： 通讯处理
*
*  配 置： 
*
*  注 意：  
*
*  作 者： zj
*
*  版 本： V1.0     
*
*  日 期： 2010-06-19
*
*        Copyright (c) 2008-2009   Brand-NEW C.A.P Electronics Technology CO.,LTD
*
**************************************************************************************************************
*/

#include "..\..\Prj\INC\LIB_Includes.H"
#define UP_RXLENSEAT				(0x0000L)
#define UP_RXLENLEN					(0x04L)
#define UP_RXLENREMAIND				(0x02L)
#define UP_RXLENINFO				((UP_RXLENSEAT<<16)|(UP_RXLENLEN<<8)|(UP_RXLENREMAIND))
/*
**************************************************************************************************************
*										  常 量
**************************************************************************************************************
*/

/*
**************************************************************************************************************
*										  类 型
**************************************************************************************************************
*/


/*
**************************************************************************************************************
*										  变 量
**************************************************************************************************************
*/


/*
**************************************************************************************************************
*         								  函 数
**************************************************************************************************************
*/


/*
**************************************************************************************************************
*
* 函数原型：void APP_UPCash_DisTF_Server_Error( U08 err, U08 row )
*
* 函数功能：显示联机同方平台错误提示提示信息。
*
* 函数输入：err  错误代码
*			rom    需要显示的行号  0－－6
*			
*           
* 函数输出：无
*
* 函数返回：无
*   
**************************************************************************************************************
*/
U08 APP_UPCash_DisTF_Server_Error( U08 err, U08 row )
{
	U08 buf[20];
	if((err == 0x03)||(err == 0x08)||(err == 0x58)||(err == 0x99)||(err == 0xA0)||(err == 0xA1))
	{
		UP_SysCfg.QDState = 0;
	  	UP_Save_ECSysCfg();
	}
	
	//DisplayClearAll( 0 );
    switch( err )
    {
	  	case 0x01:
	        //DisplayString( 0, 0, 0, row, 0x00, " 请与发卡行联系 ", 0 );
			UP_Hook_Debug_TxData( "<-Er 请与发卡行联系\r\n" );
		    break;
	    case 0x03:
	        //DisplayString( 0, 0, 0, row, 0x00, "    无效商户    ", 0 );
			UP_Hook_Debug_TxData( "<-Er 无效商户\r\n" );
		    break;
	    case 0x04:
	        //DisplayString( 0, 0, 0, row, 0x00, "   此卡被没收   ", 0 );
			UP_Hook_Debug_TxData( "<-Er 此卡被没收\r\n" );
		    break;
		case 0x05:
	        //DisplayString( 0, 0, 0, row, 0x00, " 持卡人认证失败 ", 0 );
			UP_Hook_Debug_TxData( "<-Er 持卡人认证失败\r\n" );
		    break;
	    case 0x07:
	        //DisplayString( 0, 0, 0, row, 0x00, "  主密钥已下载  ", 0 );
			UP_Hook_Debug_TxData( "<-Er 主密钥已下载\r\n" );
		    break;
	    case 0x08:
	        //DisplayString( 0, 0, 0, row, 0x00, "  终端未签到    ", 0 );
			UP_Hook_Debug_TxData( "<-Er 终端未签到\r\n" );
			break;
		case 0x12:
	        //DisplayString( 0, 0, 0, row, 0x00, "    无效交易    ", 0 );
			UP_Hook_Debug_TxData( "<-Er 无效交易\r\n" );
		    break;
	    case 0x13:
	        //DisplayString( 0, 0, 0, row, 0x00, "    无效金额    ", 0 );
			UP_Hook_Debug_TxData( "<-Er 无效金额\r\n" );
		    break;
	    case 0x14:
	        //DisplayString( 0, 0, 0, row, 0x00, "    无效卡号    ", 0 );
			UP_Hook_Debug_TxData( "<-Er 无效卡号\r\n" );
		    break;
	    case 0x15:
	        //DisplayString( 0, 0, 0, row, 0x00, "此卡无对应发卡方", 0 );
			UP_Hook_Debug_TxData( "<-Er 此卡无对应发卡方\r\n" );
		    break;
	    case 0x16:
	        //DisplayString( 0, 0, 0, row, 0x00, "  卡账户不存在  ", 0 );
			UP_Hook_Debug_TxData( "<-Er 卡账户不存在\r\n" );
		    break;
	    case 0x18:
	        //DisplayString( 0, 0, 0, row, 0x00, "    账户未启用  ", 0 );
			UP_Hook_Debug_TxData( "<-Er 账户未启用\r\n" );
		    break;
		case 0x22:
	        //DisplayString( 0, 0, 0, row, 0x00, "操作有误，请重试", 0 );
			UP_Hook_Debug_TxData( "<-Er 操作有误，请重试\r\n" );
		    break;
		case 0x25:
	        //DisplayString( 0, 0, 0, row, 0x00, "    无原始交易  ", 0 );
			UP_Hook_Debug_TxData( "<-Er 无原始交易\r\n" );
		    break;
		case 0x30:
	        //DisplayString( 0, 0, 0, row, 0x00, "交易失败，请重试", 0 );
			UP_Hook_Debug_TxData( "<-Er 交易失败，请重试\r\n" );
		    break;
	    case 0x31:
	        //DisplayString( 0, 0, 0, row, 0x00, "当日消费金额超限", 0 );
			UP_Hook_Debug_TxData( "<-Er 当日消费金额超限\r\n" );
		    break;
	    case 0x32:
	        //DisplayString( 0, 0, 0, row, 0x00, "单笔交易金额超限", 0 );
			UP_Hook_Debug_TxData( "<-Er 单笔交易金额超限\r\n" );
		    break;
		case 0x34:
	        //DisplayString( 0, 0, 0, row, 0x00, "     作弊卡     ", 0 );
			UP_Hook_Debug_TxData( "<-Er 作弊卡\r\n" );
		    break;
	    case 0x37:
	        //DisplayString( 0, 0, 0, 2, 0x00, "     交易失败     ", 0 );
			//DisplayString( 0, 0, 0, 4, 0x00, "   请联系发卡行   ", 0 );
			UP_Hook_Debug_TxData( "<-Er 交易失败 请联系发卡行\r\n" );
		    break;
	    case 0x38:
	        //DisplayString( 0, 0, 0, row, 0x00, "密码错误次数超限", 0 );
			UP_Hook_Debug_TxData( "<-Er 密码错误次数超限\r\n" );
		    break;
		case 0x40:
	        //DisplayString( 0, 0, 0, row, 0x00, "不支持的交易类型", 0 );
			UP_Hook_Debug_TxData( "<-Er 不支持的交易类型\r\n" );
		    break;
	    case 0x41:
	        //DisplayString( 0, 0, 0, row, 0x00, " 丢失卡，请没收 ", 0 );
			UP_Hook_Debug_TxData( "<-Er 丢失卡，请没收\r\n" );
		    break;
		case 0x43:
	        //DisplayString( 0, 0, 0, row, 0x00, " 被窃卡，请没收 ", 0 );
			UP_Hook_Debug_TxData( "<-Er 被窃卡，请没收\r\n" );
		    break;
	    case 0x51:
	        //DisplayString( 0, 0, 0, row, 0x00, "余额不足，请查询", 0 );
			UP_Hook_Debug_TxData( "<-Er 余额不足，请查询\r\n" );
		    break;
		case 0x54:
	        //DisplayString( 0, 0, 0, row, 0x00, "     过期卡     ", 0 );
			UP_Hook_Debug_TxData( "<-Er 过期卡\r\n" );
		    break;
	    case 0x55:
	        //DisplayString( 0, 0, 0, row, 0x00, "    密码错误    ", 0 );
			UP_Hook_Debug_TxData( "<-Er 密码错误\r\n" );
		    break;
		 case 0x57:
	        //DisplayString( 0, 0, 0, row, 0x00, "    交易失败    ", 0 );
			UP_Hook_Debug_TxData( "<-Er 交易失败\r\n" );
		    break;
		 case 0x58:
	        //DisplayString( 0, 0, 0, row, 0x00, "    终端无效    ", 0 );
			UP_Hook_Debug_TxData( "<-Er 终端无效\r\n" );
		    break;
	    case 0x61:
	        //DisplayString( 0, 0, 0, row, 0x00, "  交易金额太大  ", 0 );
			UP_Hook_Debug_TxData( "<-Er 交易金额太大\r\n" );
		    break;
		case 0x62:
	        //DisplayString( 0, 0, 0, row, 0x00, "   受限制的卡   ", 0 );
			UP_Hook_Debug_TxData( "<-Er 受限制的卡\r\n" );
		    break;
	    case 0x63:
	        //DisplayString( 0, 0, 0, row, 0x00, " 余额信息被篡改 ", 0 );
			UP_Hook_Debug_TxData( "<-Er 余额信息被篡改\r\n" );
		    break;
		case 0x65:
	        //DisplayString( 0, 0, 0, row, 0x00, "超出消费次数限制", 0 );
			UP_Hook_Debug_TxData( "<-Er 超出消费次数限制\r\n" );
		    break;
		case 0x68:
	        //DisplayString( 0, 0, 0, row, 0x00, "交易超时，请重试", 0 );
			UP_Hook_Debug_TxData( "<-Er 交易超时，请重试\r\n" );
		    break;
	    case 0x75:
	        //DisplayString( 0, 0, 0, row, 0x00, "密码错误次数超限", 0 );
			UP_Hook_Debug_TxData( "<-Er 密码错误次数超限\r\n" );
		    break;
		case 0x90:
		case 0x91:
		case 0x92:
	        //DisplayString( 0, 0, 0, row, 0x00, "   请稍后重试   ", 0 );
			UP_Hook_Debug_TxData( "<-Er 请稍后重试\r\n" );
		    break;
		case 0x94:
	        //DisplayString( 0, 0, 0, row, 0x00, " 拒绝，重复交易 ", 0 );
			UP_Hook_Debug_TxData( "<-Er 拒绝，重复交易\r\n" );
		    break;
		case 0x96:
	        //DisplayString( 0, 0, 0, row, 0x00, " 拒绝，系统出错 ", 0 );
			UP_Hook_Debug_TxData( "<-Er 拒绝，系统出错\r\n" );
		    break;
	    case 0x97:
	        //DisplayString( 0, 0, 0, row, 0x00, "   终端未登记   ", 0 );
			UP_Hook_Debug_TxData( "<-Er 拒绝，终端未登记\r\n" );
		    break;
		case 0x98:
	        //DisplayString( 0, 0, 0, row, 0x00, "交易超时，请重试", 0 );
			UP_Hook_Debug_TxData( "<-Er 交易超时，请重试\r\n" );
		    break;
	    case 0x99:
	        //DisplayString( 0, 0, 0, 3, 0x00, "      校验错    ", 0 );
			//DisplayString( 0, 0, 0, 5, 0x00, "    请重新签到  ", 0 );
			UP_Hook_Debug_TxData( "<-Er 校验错，请重新签到\r\n" );
		    return 0xff;
	    case 0xA0:
	        //DisplayString( 0, 0, 0, 3, 0x00, "    MAC校验错   ", 0 );
			//DisplayString( 0, 0, 0, 5, 0x00, "    请重新签到  ", 0 );
			UP_Hook_Debug_TxData( "<-Er MAC校验错，请重新签到\r\n" );
		    return 0xff;
	    case 0xA1:
	        //DisplayString( 0, 0, 0, 3, 0x00, "   MAC1校验错   ", 0 );
			//DisplayString( 0, 0, 0, 5, 0x00, "   请重新签到   ", 0 );
			UP_Hook_Debug_TxData( "<-Er MAC校验错，请重新签到\r\n" );
			return 0xff;
	    default :		   
			sprintf( (char*)buf, "  未知错误:%02X   ", err );	
			UP_Hook_Debug_TxData( buf );
			UP_Hook_Debug_TxData( "\r\n" );	  
			//DisplayString( 0, 0, 0, row, 0, buf, 0 );
			break;
	}
	return 1;
}
/*
**************************************************************************************************************
*Iso8583 报文初始化
Information8583SetRcv[0]  -----> 1域
Information8583SetRcv[1]  -----> 2域
		.				  	   .
		.				  	   .
		.				  	   .
Information8583SetRcv[63] ----->64域
**************************************************************************************************************
*/
void APP_8583_Init( __8583Information  *Information8583Set)
{
	Information8583Set[0].Seat = 0;
	Information8583Set[0].LenLen = 0;
	Information8583Set[0].DataLen = 0;
	Information8583Set[1].Seat = 0;
	Information8583Set[1].LenLen = 1;
	Information8583Set[1].DataLen = 0;
	Information8583Set[2].Seat = 0;
	Information8583Set[2].LenLen = 0;
	Information8583Set[2].DataLen = 3;
	Information8583Set[3].Seat = 0;
	Information8583Set[3].LenLen = 0;
	Information8583Set[3].DataLen = 6;
	Information8583Set[10].Seat = 0;
	Information8583Set[10].LenLen = 0;
	Information8583Set[10].DataLen = 3;
	Information8583Set[11].Seat = 0;
	Information8583Set[11].LenLen = 0;
	Information8583Set[11].DataLen = 3;
	Information8583Set[12].Seat = 0;
	Information8583Set[12].LenLen = 0;
	Information8583Set[12].DataLen = 2;
	Information8583Set[13].Seat = 0;
	Information8583Set[13].LenLen = 0;
	Information8583Set[13].DataLen = 2;
	Information8583Set[14].Seat = 0;
	Information8583Set[14].LenLen = 0;
	Information8583Set[14].DataLen = 2;
	Information8583Set[21].Seat = 0;
	Information8583Set[21].LenLen = 0;
	Information8583Set[21].DataLen = 2;
	Information8583Set[22].Seat = 0;
	Information8583Set[22].LenLen = 0;
	Information8583Set[22].DataLen = 2;
	Information8583Set[24].Seat = 0;
	Information8583Set[24].LenLen = 0;
	Information8583Set[24].DataLen = 1;
	Information8583Set[25].Seat = 0;
	Information8583Set[25].LenLen = 0;
	Information8583Set[25].DataLen = 1;
	Information8583Set[31].Seat = 0;
	Information8583Set[31].LenLen = 1;
	Information8583Set[31].DataLen = 0;
	Information8583Set[36].Seat = 0;
	Information8583Set[36].LenLen = 0;
	Information8583Set[36].DataLen = 12;
	Information8583Set[37].Seat = 0;
	Information8583Set[37].LenLen = 0;
	Information8583Set[37].DataLen = 6;
	Information8583Set[38].Seat = 0;
	Information8583Set[38].LenLen = 0;
	Information8583Set[38].DataLen = 2;
	Information8583Set[40].Seat = 0;
	Information8583Set[40].LenLen = 0;
	Information8583Set[40].DataLen = 8;
	Information8583Set[41].Seat = 0;
	Information8583Set[41].LenLen = 0;
	Information8583Set[41].DataLen = 15;
	Information8583Set[43].Seat = 0;
	Information8583Set[43].LenLen = 1;
	Information8583Set[43].DataLen = 0;
	Information8583Set[47].Seat = 0;
	Information8583Set[47].LenLen = 2;
	Information8583Set[47].DataLen = 0;
	Information8583Set[48].Seat = 0;
	Information8583Set[48].LenLen = 0;
	Information8583Set[48].DataLen = 3;
	Information8583Set[51].Seat = 0;
	Information8583Set[51].LenLen = 0;
	Information8583Set[51].DataLen = 8;
	Information8583Set[52].Seat = 0;
	Information8583Set[52].LenLen = 0;
	Information8583Set[52].DataLen = 8;
	Information8583Set[54].Seat = 0;
	Information8583Set[54].LenLen = 2;
	Information8583Set[54].DataLen = 0;
	Information8583Set[59].Seat = 0;
	Information8583Set[59].LenLen = 2;
	Information8583Set[59].DataLen = 0;
	Information8583Set[60].Seat = 0;
	Information8583Set[60].LenLen = 2;
	Information8583Set[60].DataLen = 0;
	Information8583Set[61].Seat = 0;
	Information8583Set[61].LenLen = 2;
	Information8583Set[61].DataLen = 0;
	Information8583Set[62].Seat = 0;
	Information8583Set[62].LenLen = 2;
	Information8583Set[62].DataLen = 0;
	Information8583Set[63].Seat = 0;
	Information8583Set[63].LenLen = 0;
	Information8583Set[63].DataLen = 8;
}
/*
**************************************************************************************************************
*Iso8583 报文解析
**************************************************************************************************************
*/
U32 APP_8583_Analysis( __8583Information  *Information8583SetRcv, U08 *SeatBuf, U08 *DataBuf, U32 BufferLen)
{
	U16 len = 0;
	U08 i,rbuf[5];
	U64 buf = 0,seat=1;
	APP_8583_Init(Information8583SetRcv);
	for(i=0;i<8;i++)
	{
		buf = ((buf<<8) | SeatBuf[i]);
	}
	len += 23;
	for(i=0;i<64;i++)
	{
		if(buf&(seat<<(63-i)))
		{
			memset(rbuf, 0, 5);
			if(Information8583SetRcv[i].DataLen)
			{
				Information8583SetRcv[i].Seat = len;
				len += Information8583SetRcv[i].DataLen;
			}
			else
			{	
				if(Information8583SetRcv[i].LenLen == 1)
				{
					sprintf((char*)rbuf,"%02X",DataBuf[len]);
					Information8583SetRcv[i].DataLen = (U16)atoi((const char*)rbuf);
					len += 1;
					Information8583SetRcv[i].Seat = len;
					if((i==1)||(i==31)||(i==47)||(i==59)||(i==60))
					{
						Information8583SetRcv[i].DataLen =	Information8583SetRcv[i].DataLen/2 + Information8583SetRcv[i].DataLen%2;
					}
				}
				else if(Information8583SetRcv[i].LenLen == 2)
				{
					sprintf((char*)rbuf,"%02X%02X", DataBuf[len], DataBuf[len+1]);
					Information8583SetRcv[i].DataLen = (U16)atoi((const char*)rbuf);
					len += 2;
					Information8583SetRcv[i].Seat = len;
					if((i==1)||(i==31)||(i==47)||(i==59)||(i==60))
					{
						Information8583SetRcv[i].DataLen =	Information8583SetRcv[i].DataLen/2 + Information8583SetRcv[i].DataLen%2;
					}
				}
				else
				{
					DEF_UPCash_Debug;
					return 1;
				}
				len += Information8583SetRcv[i].DataLen;
			}	
		}
	}
	if(len>BufferLen)
	{
		DEF_UPCash_Debug;
		return 1;
	}
	return 0;
}
/*
**************************************************************************************************************
*Iso8583 更新日期时间
**************************************************************************************************************
*/
void UpdateDayAndTime(U08 *time, U08 *day, U08 *rev_buf)
{
	U08 buf[12];
	RTC_CLOCK	rtc_time;
	buf[0] = SYS_RTC_Time.Year_H;
	buf[1] = SYS_RTC_Time.Year_L;
	buf[2] = SYS_RTC_Time.Month;
	buf[3] = SYS_RTC_Time.Day;
	buf[4] = SYS_RTC_Time.Hour;
	buf[5] = SYS_RTC_Time.Minute;	   //系统时间
	buf[6] = SYS_RTC_Time.Second;
	buf[7] = day[0];
	buf[8] = day[1];
	buf[9] = time[0];
	buf[10] = time[1];	
	buf[11] = time[2];                 		               				 
	if (memcmp(&buf[2], &buf[7], 5) != 0 )
	{															 						                 			
		rtc_time.Year_H = SYS_RTC_Time.Year_H;
		rtc_time.Year_L = SYS_RTC_Time.Year_L;
		rtc_time.Month  = day[0];
		rtc_time.Day    = day[1];
		rtc_time.Hour   = time[0];
		rtc_time.Minute = time[1];	
		rtc_time.Second = time[2];	
		rtc_time.Week	= 0;

		RTC_WriteSysTime( &rtc_time );         				//保存系统时间 
		RTC_ReadSysTime( &SYS_RTC_Time );			   		//重新获取系统时间
	}
}

/*
**************************************************************************************************************
* 名称: 签到
* 功能: 签到业务
* 入口: mode: 0,发起签到前,先连接服务器
              1,发起签到前,先判断记录上传状态和结算状态
			  2,直接签到
* 出口:	无
* 返回: 0,成功; 非0,失败 
***************************************************************************************************************/
U32 APP_8583_QD( void )
{
	U32 rcode, i;
	U08 count=0;
	U08 send_buf[200],rbuf[5];
	U32 send_size;
	U08 PIK[8]={0};
	U08 MAK[8]={0};
	U08 rev_buf[1024];
	U32 rev_size;
	__8583Information  Information8583SetRcv[64];
	
	//发送签到数据
	if( AH_Comm_8583_QD( send_buf, &send_size, 1 ) != 0 )		
	{ return 1; }
	for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
	{
		rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );		
		if( rcode != 0 )											//发送数据
		{ 
			UP_Com_Count[6]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[7]++;
		rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
		{ 
			UP_Com_Count[4]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[5]++;
		rcode = APP_8583_DealSta( rev_buf[9] & 0x0F );
//		if(( rcode != 0 ) && ( rcode != 4 ))
//		{ DEF_UPCash_Debug; continue;	}	
		if((rev_buf[13] !=0x08 )||(rev_buf[14] !=0x10 ))
		{ DEF_UPCash_Debug; continue;	}
		rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size );
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue; }
		if((rev_buf[Information8583SetRcv[38].Seat] !=0x30 )||(rev_buf[Information8583SetRcv[38].Seat+1] !=0x30 ))
		{	
			if(count==0)
			{
				count++; 
				memcpy(&send_buf[52],&rev_buf[Information8583SetRcv[59].Seat+1], 3);
				DEF_UPCash_Debug;
				continue;
			}
			memset(rbuf, 0, 5);
			CurCalc_ASCII_Proc( 2, &rev_buf[Information8583SetRcv[38].Seat], 2, rbuf, 0 );
			//if(mode != 2)
			{APP_UPCash_DisTF_Server_Error( rbuf[0], 5 );}
			DEF_UPCash_Debug;
			return 1;
		}
		if(memcmp(&rev_buf[Information8583SetRcv[10].Seat], &send_buf[23], 3) != 0 )
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], &send_buf[26], 8) != 0 )
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], &send_buf[34], 15) != 0 )
		{ DEF_UPCash_Debug; continue; }
		memset(PIK,0,8);
		CurCalc_DES_DesOperation (&rev_buf[Information8583SetRcv[61].Seat], 		
					         (unsigned char *)0x00, 			      //对PINkek进行DES解密，校验
							 UP_SysCfg.Key, 
							 TRIPLE_DES_DECRYPTION_D1E2D1 | ZERO_CBC_IV, 
							 2) ;

		memcpy( UP_SysCfg.PINkek , &rev_buf[Information8583SetRcv[61].Seat] , 16 );			 
																	  //保存PINkek 
		CurCalc_DES_DesOperation ( PIK, 								  //解密后的结果对8Byte全0做DES运算
							  (unsigned char *)0x00, 
							  &rev_buf[Information8583SetRcv[61].Seat], 
							  TRIPLE_DES_ENCRYPTION_E1D2E1 | ZERO_CBC_IV, 
							  1) ;
		if( memcmp( PIK, &rev_buf[Information8583SetRcv[61].Seat+16], 4 ) != 0 )
		{
			rcode = 0xffffffff;
			UP_Hook_Debug_TxData( "<-Er PIK错误\r\n" );
			DEF_UPCash_Debug;
			goto ER_Por;
		}		   
		memset(MAK,0,8);
		CurCalc_DES_DesOperation (&rev_buf[Information8583SetRcv[61].Seat+20], 		 
					          (unsigned char *)0x00, 				//对MACkek进行DES解密，校验
							  UP_SysCfg.Key, 
							  TRIPLE_DES_DECRYPTION_D1E2D1 | ZERO_CBC_IV, 
							  1) ;

		memcpy( UP_SysCfg.MACkek , &rev_buf[Information8583SetRcv[61].Seat+20] , 8 );	  
																	//保存MACkek 
		CurCalc_DES_DesOperation ( MAK, 								//解密后的结果对8Byte全0做DES运算
							   (unsigned char *)0x00, 
							   &rev_buf[Information8583SetRcv[61].Seat+20], 
							   SINGLE_DES_ENCRYPTION | ZERO_CBC_IV, 
							   1) ;

		if( memcmp( MAK, &rev_buf[Information8583SetRcv[61].Seat+36], 4 ) != 0 )
	    {
			rcode = 0xffffffff;
			UP_Hook_Debug_TxData( "<-Er MAK错误\r\n" );
			DEF_UPCash_Debug;
			goto ER_Por;
	    }

		UpdateDayAndTime(&rev_buf[Information8583SetRcv[11].Seat],&rev_buf[Information8583SetRcv[12].Seat],rev_buf);
		memcpy(UP_SysCfg.ComSn, &rev_buf[Information8583SetRcv[59].Seat+1], 3);
		break;														//发送成功	
	}
	if( i >= UP_UPCash_Com_ErrMaxNum )								//发送失败
	{ DEF_UPCash_Debug; return 2;	}

	UP_SysCfg.QDState = 1;	   										//签到成功
	UP_SysCfg.QDTime[0] = SYS_RTC_Time.Year_H;
    UP_SysCfg.QDTime[1] = SYS_RTC_Time.Year_L;
    UP_SysCfg.QDTime[2] = SYS_RTC_Time.Month;
    UP_SysCfg.QDTime[3] = SYS_RTC_Time.Day;
	UP_SysCfg.QDTime[4] = SYS_RTC_Time.Hour;
    UP_SysCfg.QDTime[5] = SYS_RTC_Time.Minute;
    UP_SysCfg.QDTime[6] = SYS_RTC_Time.Second;	
	rcode = UP_Write_SysCfg( &UP_SysCfg );
	if( rcode == 0 )
	{ return rcode; }

	ER_Por:
	UP_Read_SysCfg( &UP_SysCfg );
	return rcode;
}
U32 ANCheck(U08 *buf, U32 len)
{
	U32 i;
	for(i=0;i<len;i++)
	{
	 	if(((buf[i]>='0')&&(buf[i]<='9'))||((buf[i]>='a')&&(buf[i]<='z'))||((buf[i]>='A')&&(buf[i]<='Z')))
		{
			continue;
		}
		else
		{
			return 1;
		}
	}
	return 0;
}
/***************************************************************************************************************
* 功能: 银联批上送
* 功能: 在对账不平的时候上送记录
* 入口: mode,0,发送数据前不连服务器
             1,发送数据前连接服务器
* 出口: 无
* 返回: 无
***************************************************************************************************************/
U32 APP_8583_BatchRec( U08 *recbuf, U08 *retbuf )
{
	U32 rcode, i;
	U08 send_buf[512],rbuf[10];
	U32 send_size;
	U08 rev_buf[750],TMac[8]={0};
	U32 rev_size;
	__8583Information  Information8583SetRcv[64];
	U32 temp;
//	static U32 Rcv36Stat=0;
	memset(rbuf,0,10);

    //发送接收处理
	for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
	{
		rcode = AH_Comm_8583_BatchRec( send_buf, &send_size, 1, recbuf );	//获取消费记录
		if( rcode != 0 )
		{ 
			DEF_UPCash_Debug;
			return rcode; 
		}

		rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );													//发送数据
		if( rcode != 0 )											//发送数据
		{ 
			UP_Com_Count[6]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[7]++;
		rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
		{ 
			UP_Com_Count[4]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[5]++;
		rcode = APP_8583_DealSta( rev_buf[9]&0x0f );
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue; }
		if((rev_buf[13] !=0x02 )||(rev_buf[14] !=0x10 ))
		{ DEF_UPCash_Debug; continue; }
		temp = rev_size;
		rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size);
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue; }
		
		rcode = 33+(send_buf[23]-6)/2+(send_buf[23]-6)%2;
		if(rcode>500)
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[10].Seat], &send_buf[rcode], 3) != 0 )
		{ DEF_UPCash_Debug; continue; }
		//if(send_buf[16]&0x04)
		//{rcode+=8;}
		//else
		//{rcode+=6;}
		if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], UP_PosTLVSet.TVL9F1CData, 8) != 0 )
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], UP_PosTLVSet.TVL9F16Data, 15) != 0 )
		{ DEF_UPCash_Debug; continue; }
		
		if((rev_buf[Information8583SetRcv[38].Seat] !=0x30 )||(rev_buf[Information8583SetRcv[38].Seat+1] !=0x30 ))
		{	
			if((rev_buf[Information8583SetRcv[38].Seat] ==0x39 )&&(rev_buf[Information8583SetRcv[38].Seat+1] ==0x34 ))
			{			   
				if(Information8583SetRcv[36].Seat == 0)
				{ DEF_UPCash_Debug; continue; }
				if(ANCheck(&rev_buf[Information8583SetRcv[36].Seat], 12))
				{ DEF_UPCash_Debug; continue; }
				//MAC验证
				if(Information8583SetRcv[63].Seat)
				{
					UP_Get_MAC( &rev_buf[13], temp-21, UP_SysCfg.MACkek, TMac );
					if( memcmp( TMac, &rev_buf[Information8583SetRcv[63].Seat], 8 ) != 0 )
					{ 
						DEF_UPCash_Debug; 
						UP_SysCfg.QDState = 0;
					  	UP_Save_ECSysCfg();
						return 1; 
					}
				}
				goto kk;
			}
			if((rev_buf[Information8583SetRcv[38].Seat] ==0x31 )&&(rev_buf[Information8583SetRcv[38].Seat+1] ==0x33 ))
			{
				if(UP_rcdSendMoney==0)
				{goto kk1;}
			}
//			if((rev_buf[Information8583SetRcv[38].Seat] ==0x39 )&&(rev_buf[Information8583SetRcv[38].Seat+1] ==0x36 ))
//			{ 
//				DEF_UPCash_Debug;
//				return 1; 
//			}
				
			memset(rbuf, 0, 5);
			CurCalc_ASCII_Proc( 2, &rev_buf[Information8583SetRcv[38].Seat], 2, rbuf, 0 );
			APP_UPCash_DisTF_Server_Error( rbuf[0], 5 );
			DEF_UPCash_Debug;
			return 1;
		}
		if(Information8583SetRcv[36].Seat == 0)
		{ DEF_UPCash_Debug; continue; }
		if(ANCheck(&rev_buf[Information8583SetRcv[36].Seat], 12))
		{ DEF_UPCash_Debug; continue; }
		//MAC验证
		UP_Get_MAC( &rev_buf[13], temp-21, UP_SysCfg.MACkek, TMac );
		if( memcmp( TMac, &rev_buf[Information8583SetRcv[63].Seat], 8 ) != 0 )
		{ 
			DEF_UPCash_Debug; 
			UP_SysCfg.QDState = 0;
		  	UP_Save_ECSysCfg();
			return 1; 
		}
		//UpdateDayAndTime(&rev_buf[Information8583SetRcv[11].Seat],&rev_buf[Information8583SetRcv[12].Seat],rev_buf);
		kk:
		UP_CommStatPar.BatchRecNum ++;
		UP_CommStatPar.BatchRecMoney += UP_rcdSendMoney;
		rcode = UP_Write_ComCfg( &UP_CommStatPar );
		kk1:
		//银联记录返回信息存储
		memcpy(&retbuf[0], recbuf, 4);	//本条记录终端流水号
		memcpy(&retbuf[4], &rev_buf[Information8583SetRcv[11].Seat], 3);	//12域 
		memcpy(&retbuf[7], &rev_buf[Information8583SetRcv[12].Seat], 2);	//13域
		memcpy(&retbuf[9], &rev_buf[Information8583SetRcv[14].Seat], 2);	//15域
		memcpy(&retbuf[11], &rev_buf[Information8583SetRcv[36].Seat], 12);	//37域
		memcpy(&retbuf[23], &rev_buf[Information8583SetRcv[38].Seat], 2);	//39域
		memcpy(&retbuf[25], &rev_buf[Information8583SetRcv[59].Seat+1], 3);	//60.2域
		 
		return 0;					
	}

	DEF_UPCash_Debug;
	return 1;	
}

/***************************************************************************************************************
* 名称:银联批结算
* 功能:
* 入口:无
* 出口
* 返回:0,对账平,结算正常,对账不平
       非0,或出错 
***************************************************************************************************************/
U32 APP_8583_Batch( void )
{
	U32 rcode, i;
	U08 send_buf[512],sta=0;
	U32 send_size;
	U08 rev_buf[1024];
	U32 rev_size;
	__8583Information  Information8583SetRcv[64];
	U08 buf[20];
	U32 data1,data2;
	U08 data3,data4;

	if( UP_SysCfg.BatchSta != 0 )
	{ return 0; }

	if( AH_Comm_8583_Batch( send_buf, &send_size ) != 0 )		
	{ return 2; }
	
	for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
	{
		rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );		
		if( rcode != 0 )											//发送数据
		{ 
			UP_Com_Count[6]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[7]++;
		rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
		{ 
			UP_Com_Count[4]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[5]++;
		rcode = APP_8583_DealSta( rev_buf[9]&0x0f );
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue; }		
		if((rev_buf[13] !=0x05 )||(rev_buf[14] !=0x10 ))
		{ DEF_UPCash_Debug; continue; }
		rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size);
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[10].Seat], &send_buf[23], 3) != 0 )
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], UP_PosTLVSet.TVL9F1CData, 8) != 0 )
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], UP_PosTLVSet.TVL9F16Data, 15) != 0 )
		{ DEF_UPCash_Debug; continue; }
		sta=(rev_buf[Information8583SetRcv[47].Seat+15]&0xf0)|(rev_buf[Information8583SetRcv[47].Seat+30]&0x0f);
	
		memcpy(UP_SysCfg.BatchTime,&rev_buf[Information8583SetRcv[12].Seat],2);
		memcpy(UP_SysCfg.BatchTime+2,&rev_buf[Information8583SetRcv[11].Seat],3);
		rcode = UP_Write_SysCfg( &UP_SysCfg );
		if( rcode != 0 )											//写用户文件
		{ 
			DEF_UPCash_Debug;
			return rcode; 
		}
		break;					
	}
	if( i >= UP_UPCash_Com_ErrMaxNum )								//发送失败
	{ DEF_UPCash_Debug; return 2; }

	CurCalc_HEXtoBCD_Proc( 1, &rev_buf[Information8583SetRcv[47].Seat], 8, buf, 16, 0 );	//bcd->ascii
	CurCalc_ASCII_Proc( 3, &buf[0], 12, 0, &data1 );				 	//ascii-->hex
	CurCalc_ASCII_Proc( 3, &buf[12], 3, 0, &data2 );
	data3 = (rev_buf[Information8583SetRcv[47].Seat+15]>>4)&0x0F;	//内卡对账平标志
	data4 = (rev_buf[Information8583SetRcv[48].Seat-1])&0x0F;	 	//外卡对账平标志
	data3 = data3; data4 = data4;
	//只比较内卡对账标志
	if( sta == 17 )
	{
		UP_SysCfg.BatchSta = 1;	   									//对帐平
		UP_SysCfg.Rec_rSendStat = 0;								//记录重传
		rcode = UP_Write_SysCfg( &UP_SysCfg ); 
		if( rcode != 0 )
		{ 
			DEF_UPCash_Debug;
			return rcode; 
		}
		return 0;
	}
	else if( ( (sta&0x30)==0x30 ) || ((sta&0x03)==0x03) )
	{ 
		UP_SysCfg.BatchSta = 1;										//对帐平
		UP_SysCfg.Rec_rSendStat = 0;								//记录重传
		rcode = UP_Write_SysCfg( &UP_SysCfg ); 
		if( rcode != 0 )
		{ 
			DEF_UPCash_Debug;
			return rcode; 
		}
		return 0;	 
	}

	UP_SysCfg.BatchSta = 2;	  										//帐不平
	UP_SysCfg.Rec_rSendStat = 1;			 						//记录重传
	rcode = UP_Write_SysCfg( &UP_SysCfg ); 
	if( rcode != 0 )
	{ 
		DEF_UPCash_Debug;
		return rcode; 
	}
	return 0;
}
/*
**************************************************************************************************************
* 功能: 银联批上送2
* 功能: 在对账不平的时候上送记录
* 入口: mode,0,发送数据前不连服务器
             1,发送数据前连接服务器
* 出口: 无
* 返回: 无
**************************************************************************************************************
*/
U32 APP_8583_BatchRecT( U08 *recbuf )
{
	U32 rcode,i;
	U08 send_buf[512],rbuf[5];
	U32 send_size;
	U08 rev_buf[750];
	U32 rev_size;
	__8583Information  Information8583SetRcv[64];

	for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
	{
		rcode = AH_Comm_8583_BatchRec( send_buf, &send_size, 0, recbuf );	
		if( rcode != 0 )											//获取消费记录
		{ return rcode; }
		
		rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );		
		if( rcode != 0 )											//发送数据
		{ 
			UP_Com_Count[6]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[7]++;
		rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
		{ 
			UP_Com_Count[4]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[5]++;
		rcode = APP_8583_DealSta( rev_buf[9]&0x0f );
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue; }
		if((rev_buf[13] !=0x03 )||(rev_buf[14] !=0x30 ))
		{ DEF_UPCash_Debug; continue; }
		rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size);
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue; }
		if((rev_buf[Information8583SetRcv[38].Seat] !=0x30 )||(rev_buf[Information8583SetRcv[38].Seat+1] !=0x30 ))
		{	
			if((rev_buf[Information8583SetRcv[38].Seat] ==0x39 )&&(rev_buf[Information8583SetRcv[38].Seat+1] ==0x34 ))
			{goto kk;}
			if((rev_buf[Information8583SetRcv[38].Seat] ==0x31 )&&(rev_buf[Information8583SetRcv[38].Seat+1] ==0x33 ))
			{
				if(UP_rcdSendMoney==0)
				{goto kk;}
			}
//			if((rev_buf[Information8583SetRcv[38].Seat] ==0x39 )&&(rev_buf[Information8583SetRcv[38].Seat+1] ==0x36 ))
//			{goto kk;}
			memset(rbuf, 0, 5);
			CurCalc_ASCII_Proc( 2, &rev_buf[Information8583SetRcv[38].Seat], 2, rbuf, 0 );
		    APP_UPCash_DisTF_Server_Error( rbuf[0], 5 );
			DEF_UPCash_Debug;
			return 1;
		}

		if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], UP_PosTLVSet.TVL9F1CData, 8) != 0 )
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], UP_PosTLVSet.TVL9F16Data, 15) != 0 )
		{ DEF_UPCash_Debug; continue; }

		kk:
		return 0;
	}

	DEF_UPCash_Debug;
	return 1;
}

/*
**************************************************************************************************************
* 名称: 银联批上送结束通讯处理
* 入口: mode, 2,对账不平,上送报文中:60.3="207",UP_CommStatPar.BatchSta = 4;
              1,对帐平,  上送报文中:60.3="202",UP_CommStatPar.BatchSta = 6;
* 出口:	无
* 返回: 0,成功
        1,交易失败
        2,硬件相关的失败
**************************************************************************************************************
*/
U32 APP_8583_BatchOver( void )
{
	U32 rcode, i;
	U08 send_buf[512],rbuf[5];
	U32 send_size;
	U08 rev_buf[1024];
	U32 rev_size;
	__8583Information  Information8583SetRcv[64];

	if( UP_SysCfg.BatchSta == 0 )
	{ return 0; }

	if( AH_Comm_8583_BatchOver( send_buf, &send_size, UP_SysCfg.BatchSta ) != 0 )		
	{ return 2; }

	for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
	{
		rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );		
		if( rcode != 0 )											//发送数据
		{ 
			UP_Com_Count[6]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[7]++;
		rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
		{ 
			UP_Com_Count[4]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[5]++;
		rcode = APP_8583_DealSta( rev_buf[9]&0x0f );
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue; }
		if((rev_buf[13] !=0x03 )||(rev_buf[14] !=0x30 ))
		{ DEF_UPCash_Debug; continue; }
		rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size);
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue; }
		if((rev_buf[Information8583SetRcv[38].Seat] !=0x30 )||(rev_buf[Information8583SetRcv[38].Seat+1] !=0x30 ))
		{	
			if((rev_buf[Information8583SetRcv[38].Seat] ==0x39 )&&(rev_buf[Information8583SetRcv[38].Seat+1] ==0x36 ))
			{break;}
			memset(rbuf, 0, 5);
			CurCalc_ASCII_Proc( 2, &rev_buf[Information8583SetRcv[38].Seat], 2, rbuf, 0 );
		    APP_UPCash_DisTF_Server_Error( rbuf[0], 5 );
			DEF_UPCash_Debug;
			return 1;
		}
		if(memcmp(&rev_buf[Information8583SetRcv[10].Seat], &send_buf[23], 3) != 0 )
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], &send_buf[26], 8) != 0 )
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], &send_buf[34], 15) != 0 )
		{ DEF_UPCash_Debug; continue; }
		
		break;					
	}
	if( i >= UP_UPCash_Com_ErrMaxNum )								//发送失败
	{ DEF_UPCash_Debug; return 2; }

	//批结算结束
	UP_SysCfg.BatchSta = 0;									//下
	UP_SysCfg.Rec_rSendStat = 0;   							//记录不用重传
//	UP_SysCfg.QDState = 0; //这里的签到状态不改，由记录里自动处理???
	UP_SysCfg.QDTime[0] = SYS_RTC_Time.Year_H;
    UP_SysCfg.QDTime[1] = SYS_RTC_Time.Year_L;
    UP_SysCfg.QDTime[2] = SYS_RTC_Time.Month;
    UP_SysCfg.QDTime[3] = SYS_RTC_Time.Day;
	UP_SysCfg.QDTime[4] = SYS_RTC_Time.Hour;
    UP_SysCfg.QDTime[5] = SYS_RTC_Time.Minute;
    UP_SysCfg.QDTime[6] = SYS_RTC_Time.Second;	
	rcode = UP_Write_SysCfg( &UP_SysCfg );
	if( rcode != 0 )
	{
		DEF_UPCash_Debug;
		UP_Read_SysCfg( &UP_SysCfg );
	}
	
	UP_CommStatPar.BatchRecNum = 0;
	UP_CommStatPar.BatchRecMoney = 0;
	rcode = UP_Write_ComCfg( &UP_CommStatPar );;
	if( rcode != 0 )										//写用户文件
	{ return 2; }
	
	return 0;
}

/*
**************************************************************************************************************
*Iso8583 公钥下载相关
**************************************************************************************************************
*/
U32 APP_Get_AIDIndex( U08 *tlvData, U08 Num, U08 *size )
{
	U08 i,len=0;
	U16 TlvLenTmp;
	for(i=0;i<Num;i++)
	{
		if ( (tlvData[len]&0x20) != 0x20)//单一结构
       	{

              if ( (tlvData[len]&0x1f) == 0x1f)//tag两字节
              {		
					if((tlvData[len+2])&0x80)
					{
						if((tlvData[len+2]&0x7F) == 2)
						{
							TlvLenTmp = tlvData[len+3];
							TlvLenTmp = ((TlvLenTmp<<8)|tlvData[len+4]);
							len+=(TlvLenTmp+4);
						} 
						else
						{
							len+=(tlvData[len+3]+3);
						}
					}
					else
					{
						len+=(tlvData[len+2]+2);
					}
              }

              else//tag单字节

              {		
					if((tlvData[len+1])&0x80)
					{
						if((tlvData[len+1]&0x7F) == 2)
						{
							TlvLenTmp = tlvData[len+2];
							TlvLenTmp = ((TlvLenTmp<<8)|tlvData[len+3]);
							len+=(TlvLenTmp+3);
						} 
						else
						{
							len+=(tlvData[len+2]+2);
						}
					}
					else
					{
						len+=(tlvData[len+1]+1);
					}
              }
       	}
		else
		{
			return 1;
		}
		len++;
	}
	*size = len;
	return 0;
}
/*
**************************************************************************************************************
*Iso8583 公钥下载----->状态上送
输出:  AidAndIndexBuf	   状态信息
	   AidAndIndexlen	   每条状态信息长度
	   KeyNum 			   状态信息条数
返回值:  0    成功
		 非0  失败
**************************************************************************************************************
*/
U08 APP_Comm_8583_CAKeyStaUpLoad(U08 *AidAndIndexBuf,U08 *AidAndIndexlen,U08 *KeyNum)
{
	U32 rcode, i;
	U08 send_buf[200],ParTypeAndNum[3],rbuf[5];
	U32 send_size;
	U08 rev_buf[1024];
	U32 rev_size;
	
	__8583Information  Information8583SetRcv[64];
	memcpy(ParTypeAndNum, "\x31\x30\x30", 3);
	kk:
	if( AH_Comm_8583_StaUpLoad( send_buf, &send_size,ParTypeAndNum,0) != 0 )			//状态上传
		return 1; 

	for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
	{
		OS_SleepMs(1000);
		rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );		
		if( rcode != 0 )											//发送数据
		{ 
			UP_Com_Count[6]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[7]++;
		rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
		{ 
			UP_Com_Count[4]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[5]++;
		rcode = APP_8583_DealSta( rev_buf[9]&0x0f );
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue;	}
		if((rev_buf[13] !=0x08 )||(rev_buf[14] !=0x30 ))
		{ DEF_UPCash_Debug; continue; }
		rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size);
		if( rcode != 0 )
		{ DEF_UPCash_Debug; continue; }
		if((rev_buf[Information8583SetRcv[38].Seat] !=0x30 )||(rev_buf[Information8583SetRcv[38].Seat+1] !=0x30 ))
		{	
			memset(rbuf, 0, 5);
			CurCalc_ASCII_Proc( 2, &rev_buf[Information8583SetRcv[38].Seat], 2, rbuf, 0 );
		    APP_UPCash_DisTF_Server_Error( rbuf[0], 5 );
			DEF_UPCash_Debug;
			return 17;
		}
		
		if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], &send_buf[23], 8) != 0 )
		{ DEF_UPCash_Debug; continue; }
		if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], &send_buf[31], 15) != 0 )
		{ DEF_UPCash_Debug; continue; }
		memset(rbuf, 0, 5);
		sprintf((char*)rbuf,"%02X%02X", rev_buf[Information8583SetRcv[61].Seat-2], rev_buf[Information8583SetRcv[61].Seat-1]);
		rev_size = atoi((const char*)rbuf)-1;
		if(rev_size>500)
		{ DEF_UPCash_Debug; return 1; }
		if(rev_size)
		{
			rcode = APP_Get_AIDIndex( &rev_buf[Information8583SetRcv[61].Seat+1], 3, AidAndIndexlen );
			if( rcode != 0 )
			{ DEF_UPCash_Debug; continue; }
		}
		if(rev_buf[Information8583SetRcv[61].Seat] ==0x30 )
		{	
			if(KeyNum[0])
			{ return 0; }

			DEF_UPCash_Debug;
			return 0xFF;	 
		}
		else if(rev_buf[Information8583SetRcv[61].Seat] ==0x31)
		{
			memcpy(&AidAndIndexBuf[AidAndIndexlen[0]*KeyNum[0]], &rev_buf[Information8583SetRcv[61].Seat+1], rev_size);
			KeyNum[0] += (U08)(rev_size/AidAndIndexlen[0]);
			sprintf((char*)ParTypeAndNum+1, "%02d", KeyNum[0]);
			goto kk;
		}
		else if(rev_buf[Information8583SetRcv[61].Seat] ==0x32)
		{
			memcpy(&AidAndIndexBuf[AidAndIndexlen[0]*KeyNum[0]], &rev_buf[Information8583SetRcv[61].Seat+1], rev_size);
			KeyNum[0] += (U08)(rev_size/AidAndIndexlen[0]);
			sprintf((char*)ParTypeAndNum+1, "%02d", KeyNum[0]);
			goto kk;
		}	
		else if(rev_buf[Information8583SetRcv[61].Seat] ==0x33)
		{
			memcpy(&AidAndIndexBuf[AidAndIndexlen[0]*KeyNum[0]], &rev_buf[Information8583SetRcv[61].Seat+1], rev_size);
			KeyNum[0] += (U08)(rev_size/AidAndIndexlen[0]);
		}	
//		UpdateDayAndTime(&rev_buf[Information8583SetRcv[11].Seat],&rev_buf[Information8583SetRcv[12].Seat],rev_buf);					
		break;														//发送成功	
	}
	if( i >= UP_UPCash_Com_ErrMaxNum )								//发送失败
	{ DEF_UPCash_Debug; return 1; }
	return 0;
}
/*
**************************************************************************************************************
*公钥下载时对ＴＬＶ格式的公钥数据进行解析检测及存储（公钥格式必须与银联定义的相同）
输入:  in	   						ＴＬＶ格式的公钥数据
	   inlen	   					ＴＬＶ格式的公钥数据长度
返回值:  0    成功
		 非0  失败
**************************************************************************************************************
*/	
U32 UP_CAKeyTLV_AnalysisCheckAndSave(U08 *in, U32 inlen)
{
	U32 rcode;
	U08 buf[300];
	U32 len;
	UP_CAPublicKey.TVLDF03Seat = 0;
	rcode = UP_TlvDataAnalysisAndFarming(in, (U16)inlen, buf, buf, 2);
	if(rcode)
	{
		return rcode;
	}
	if(UP_CAPublicKey.TVLDF03Seat == 0)
	{
		return 1;
	}
	len = 0;

	memcpy(&buf[len],UP_CAPublicKey.TVL9F06,UP_CAPublicKey.TVL9F06Len);
	len+=UP_CAPublicKey.TVL9F06Len;

	memcpy(&buf[len],&UP_CAPublicKey.TVL9F22,1);
	len+=1;

	memcpy(&buf[len],UP_CAPublicKey.TVLDF02,UP_CAPublicKey.TVLDF02Len);
	len+=UP_CAPublicKey.TVLDF02Len;

	memcpy(&buf[len],UP_CAPublicKey.TVLDF04,UP_CAPublicKey.TVLDF04Len);
	len+=UP_CAPublicKey.TVLDF04Len;

	rcode = CurCalc_Checksha1( buf, len, UP_CAPublicKey.TVLDF03Seat );
	if(rcode)
	{
		//DisplayString( 0, 0, 0, 6, 0x00, "  哈希校验出错  ", 0 );
		return 17;
	}
	rcode = UP_WriteRec_CAPUBKEY(&UP_CAPublicKey);	//保存记录	
	return rcode;	
}
/*
**************************************************************************************************************
*Iso8583 公钥下载----->下载公钥
输入:  AidAndIndexBuf	   状态信息
	   AidAndIndexlen	   每条状态信息长度
	   KeyNum 			   状态信息条数
返回值:  0    成功
		 非0  失败
**************************************************************************************************************
*/						
U08 APP_Comm_8583_PubKeyDownLoad(U08 *AidAndIndexBuf,U08 AidAndIndexlen,U08 KeyNum)
{
	U32 rcode, i, j;
	U08 send_buf[200],rbuf[5];
	U32 send_size, recnum;
	U08 rev_buf[1024];
	U32 rev_size;
	
	__8583Information  Information8583SetRcv[64];
	if( APP_Get_RecFileNum( UP_Rec_Config.UP_RecMemoryBank_CAPubKey, 1, &recnum ) == 0 )
	{												 	//获取未上传的记录
		if(recnum)
		{
			if(APP_Delete_RecFile( UP_Rec_Config.UP_RecMemoryBank_CAPubKey, 1, rev_buf, recnum ))
			{
				return 1;
			} 	
		}														
	}
	else
	{
		return 1;
	}	

	for(j=0;j<KeyNum*AidAndIndexlen;j+=AidAndIndexlen)
	{
		sprintf((char*)rbuf,"%02d/%02d",j/AidAndIndexlen,KeyNum);
		//DisplayString( 0, 0, 88, 4, 0x00, rbuf, 0 );
		memset(send_buf,0,sizeof(send_buf));
		if( AH_Comm_8583_PubKeyParDownLoad( send_buf, &send_size, &AidAndIndexBuf[j],AidAndIndexlen, 0 ) != 0 )			//下载公钥
			goto END;
	
		for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
		{
			OS_SleepMs(1000);
			rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );	//发送数据
			if( rcode != 0 )											//发送数据
			{ 
				UP_Com_Count[6]++;
				DEF_UPCash_Debug; 
				return rcode; 
			}
			UP_Com_Count[7]++;
			rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
	        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
			{ 
				UP_Com_Count[4]++;
				DEF_UPCash_Debug; 
				return rcode; 
			}
			UP_Com_Count[5]++;
			rcode = APP_8583_DealSta( rev_buf[9]&0x0f );
			if( rcode != 0 )
				continue;		
			if((rev_buf[13] !=0x08 )||(rev_buf[14] !=0x10 ))
				continue;
			rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size);
			if( rcode != 0 )
				continue;
			if((rev_buf[Information8583SetRcv[38].Seat] !=0x30 )||(rev_buf[Information8583SetRcv[38].Seat+1] !=0x30 ))
			{	
				memset(rbuf, 0, 5);
				CurCalc_ASCII_Proc( 2, &rev_buf[Information8583SetRcv[38].Seat], 2, rbuf, 0 );
			    APP_UPCash_DisTF_Server_Error( rbuf[0], 5 );
				goto END;
			}
			
			if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], &send_buf[23], 8) != 0 )
				continue;
			if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], &send_buf[31], 15) != 0 )
				continue;
			if(rev_buf[Information8583SetRcv[61].Seat] ==0x30)
				continue;
			memset(rbuf, 0, 5);
			sprintf((char*)rbuf,"%02X%02X", rev_buf[Information8583SetRcv[61].Seat-2], rev_buf[Information8583SetRcv[61].Seat-1]);
			rev_size = atoi((const char*)rbuf)-1;
			if(rev_size>500)
			{return 1;}
			rcode = UP_CAKeyTLV_AnalysisCheckAndSave(&rev_buf[Information8583SetRcv[61].Seat+1], rev_size);
			if( rcode != 0 )
			{return rcode;}
//			UpdateDayAndTime(&rev_buf[Information8583SetRcv[11].Seat],&rev_buf[Information8583SetRcv[12].Seat],rev_buf);
			break;														//发送成功	
		}
		if( i >= UP_UPCash_Com_ErrMaxNum )								//发送失败
			goto END;
	}
	//sprintf((char*)rbuf,"%02d/%02d",j/AidAndIndexlen,KeyNum);
	//DisplayString( 0, 0, 88, 4, 0x00, rbuf, 0 );	
	rcode = UP_CAKey_DownLoadCAkey_Load();
	if(rcode == 0)
	{
		UP_SysCfg.CAPKeyAndICParmSta &= ~1;
		UP_Save_ECSysCfg();
	}
	return rcode;

	END:
	return 1;
}
/*
**************************************************************************************************************
*Iso8583 公钥下载----->下载结束
**************************************************************************************************************
*/
U08 APP_Comm_8583_PubKeyDownLoadOver(void)
{
	U32 rcode, i;
	U08 send_buf[200],rbuf[5];
	U32 send_size;
	U08 rev_buf[1024];
	U32 rev_size;
	
	__8583Information  Information8583SetRcv[64];
	if( AH_Comm_8583_PubKeyParDownLoadOver( send_buf, &send_size, 0 ) != 0 )			//下载公钥结束
		return 3; 

	for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
	{
		OS_SleepMs(1000);
		rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );	//发送数据
		if( rcode != 0 )											//发送数据
		{ 
			UP_Com_Count[6]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[7]++;
		rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
		{ 
			UP_Com_Count[4]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[5]++;

		rcode = APP_8583_DealSta( rev_buf[9]&0x0f );
		if( rcode != 0 )
			continue;		
		if((rev_buf[13] !=0x08 )||(rev_buf[14] !=0x10 ))
			continue;
		rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size);
		if( rcode != 0 )
			continue;
		if((rev_buf[Information8583SetRcv[38].Seat] !=0x30 )||(rev_buf[Information8583SetRcv[38].Seat+1] !=0x30 ))
		{	
			memset(rbuf, 0, 5);
			CurCalc_ASCII_Proc( 2, &rev_buf[Information8583SetRcv[38].Seat], 2, rbuf, 0 );
		    APP_UPCash_DisTF_Server_Error( rbuf[0], 5 );
			return 17; 
		}
		
		if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], &send_buf[23], 8) != 0 )
			continue;
		if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], &send_buf[31], 15) != 0 )
			continue;
//		UpdateDayAndTime(&rev_buf[Information8583SetRcv[11].Seat],&rev_buf[Information8583SetRcv[12].Seat],rev_buf);
		break;														//发送成功	
	}
	if( i >= UP_UPCash_Com_ErrMaxNum )								//发送失败
		return 3; 

	return 0;
}
/*
**************************************************************************************************************
*Iso8583 公钥下载
**************************************************************************************************************
*/
U32 APP_8583_CAKeyDownLoad( void )
{
	U32 rcode;
	U08 KeyNum=0,AidAndIndexBuf[512];
	U08 AidAndIndexlen;

	rcode = APP_Comm_8583_CAKeyStaUpLoad(AidAndIndexBuf,&AidAndIndexlen,&KeyNum);	 //状态上送
	if(rcode)
	{
		return rcode;
	}
	rcode = APP_Comm_8583_PubKeyDownLoad(AidAndIndexBuf, AidAndIndexlen, KeyNum);	 //公钥下载
	if(rcode)
	{
		return rcode;
	}
	rcode = APP_Comm_8583_PubKeyDownLoadOver();				//公钥下载结束
	if(rcode)
	{
		return rcode;
	}

	return 0;
}
/*
**************************************************************************************************************
*Iso8583 IC卡参数下载----->状态上送
输出:  buf[][17]	   状态信息	(包括每条状态信息长度)	   
	   ParNum 		   状态信息条数
返回值:  0    成功
		 非0  失败
**************************************************************************************************************
*/	                                                                                                                                                                                                                                                                                                                                                                                 
U08 APP_Comm_8583_ParStaUpLoad(U08 (*buf)[17],U08 *ParNum)
{
	U32 rcode, i, j,tmp=1;
	U08 send_buf[200],ParTypeAndNum[3],rbuf[5];
	U32 send_size;
	U08 rev_buf[1024];
	U32 rev_size;
	__8583Information  Information8583SetRcv[64];
	memcpy(ParTypeAndNum, "\x31\x30\x30", 3);
	kk:
	if( AH_Comm_8583_StaUpLoad( send_buf, &send_size,ParTypeAndNum,1) != 0 )			//状态上传
		return 1; 

	for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
	{
		OS_SleepMs(1000);
		rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );	//发送数据
		if( rcode != 0 )											//发送数据
		{ 
			UP_Com_Count[6]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[7]++;
		rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
		{ 
			UP_Com_Count[4]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[5]++;

		rcode = APP_8583_DealSta( rev_buf[9]&0x0f );
		if( rcode != 0 )
			continue;		
		if((rev_buf[13] !=0x08 )||(rev_buf[14] !=0x30 ))
			continue;
		rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size);
		if( rcode != 0 )
			continue;
		if((rev_buf[Information8583SetRcv[38].Seat] !=0x30 )||(rev_buf[Information8583SetRcv[38].Seat+1] !=0x30 ))
		{	
			memset(rbuf, 0, 5);
			CurCalc_ASCII_Proc( 2, &rev_buf[Information8583SetRcv[38].Seat], 2, rbuf, 0 );
		    APP_UPCash_DisTF_Server_Error( rbuf[0], 5 );
			return 17;
		}
		
		if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], &send_buf[23], 8) != 0 )
			continue;
		if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], &send_buf[31], 15) != 0 )
			continue;
		memset(rbuf, 0, 5);
		sprintf((char*)rbuf,"%02X%02X", rev_buf[Information8583SetRcv[61].Seat-2], rev_buf[Information8583SetRcv[61].Seat-1]);
		rev_size = atoi((const char*)rbuf)-1;
		if(rev_size>500)
		{return 1;}
//		rcode = APP_Get_AIDIndex( &rev_buf[Information8583SetRcv[61].Seat+1], 3, &RIDANDINDEXLEN );
//		if( rcode != 0 )
//			continue;
		tmp = 1;
		if(rev_buf[Information8583SetRcv[61].Seat] ==0x30 )
		{	
			if(ParNum[0])
			{return 0;}
			return 0xFF;	 
		}
		else if(rev_buf[Information8583SetRcv[61].Seat] ==0x31)
		{
			for(j=0;j<rev_size;j++)
			{
				if((rev_buf[Information8583SetRcv[61].Seat+tmp]==0x9f)&&(rev_buf[Information8583SetRcv[61].Seat+tmp+1]==0x06))
				{
					buf[ParNum[0]][16] = rev_buf[Information8583SetRcv[61].Seat+tmp+2]+3;
					memcpy(&buf[ParNum[0]][0],&rev_buf[Information8583SetRcv[61].Seat+tmp],buf[ParNum[0]][16]);
					tmp+=buf[ParNum[0]][16];
					ParNum[0]++;
				}
			}
			sprintf((char*)ParTypeAndNum+1, "%02d", ParNum[0]);
			goto kk;
		}
		else if(rev_buf[Information8583SetRcv[61].Seat] ==0x32)
		{
			for(j=0;j<rev_size;j++)
			{
				if((rev_buf[Information8583SetRcv[61].Seat+tmp]==0x9f)&&(rev_buf[Information8583SetRcv[61].Seat+tmp+1]==0x06))
				{
					buf[ParNum[0]][16] = rev_buf[Information8583SetRcv[61].Seat+tmp+2]+3;
					memcpy(&buf[ParNum[0]][0],&rev_buf[Information8583SetRcv[61].Seat+tmp],buf[ParNum[0]][16]);
					tmp+=buf[ParNum[0]][16];
					ParNum[0]++;
				}
			}
			sprintf((char*)ParTypeAndNum+1, "%02d", ParNum[0]);
			goto kk;
		}	
		else if(rev_buf[Information8583SetRcv[61].Seat] ==0x33)
		{
			for(j=0;j<rev_size;j++)
			{
				if((rev_buf[Information8583SetRcv[61].Seat+tmp]==0x9f)&&(rev_buf[Information8583SetRcv[61].Seat+tmp+1]==0x06))
				{
					buf[ParNum[0]][16] = rev_buf[Information8583SetRcv[61].Seat+tmp+2]+3;
					memcpy(&buf[ParNum[0]][0],&rev_buf[Information8583SetRcv[61].Seat+tmp],buf[ParNum[0]][16]);
					tmp+=buf[ParNum[0]][16];
					ParNum[0]++;
				}
			}
		}	
//		UpdateDayAndTime(&rev_buf[Information8583SetRcv[11].Seat],&rev_buf[Information8583SetRcv[12].Seat],rev_buf);					
		break;														//发送成功	
	}
	if( i >= UP_UPCash_Com_ErrMaxNum )								//发送失败
		return 1;
	return 0;
}
/*
**************************************************************************************************************
*IC卡参数下载时对ＴＬＶ格式的公钥数据进行解析检测及存储（IC卡参数格式必须与银联定义的相同）
输入:  in	   						ＴＬＶ格式的公钥数据
	   inlen	   					ＴＬＶ格式的公钥数据长度
返回值:  0    成功
		 非0  失败
**************************************************************************************************************
*/	
U32 UP_ICParTLV_AnalysisCheckAndSave(U08 *in, U32 inlen)
{
	U32 rcode;
	U08 m;
	UP_ICPParmInit();
	rcode = UP_TlvDataAnalysisAndFarming(in, (U16)inlen, &m, &m, 2);
	if(rcode)
	{
		return rcode;
	}
	UP_ICPParm.UsefullStat = 1;
	rcode = UP_WriteRec_ICPar( &UP_ICPParm );	//保存记录	
	return rcode;	
}
U08 APP_Comm_8583_ParDownLoad(U08 (*buf)[17],U08 ParNum)
{
	U32 rcode, i, j;
	U08 send_buf[200],rbuf[5];
	U32 send_size, recnum;
	U08 rev_buf[750];
	U32 rev_size;
	
	__8583Information  Information8583SetRcv[64];
	if( APP_Get_RecFileNum( UP_Rec_Config.UP_RecMemoryBank_ICPar, 1, &recnum ) == 0 )
	{												 	//获取未上传的记录
		if(recnum)
		{
			if(APP_Delete_RecFile( UP_Rec_Config.UP_RecMemoryBank_ICPar, 1, rev_buf, recnum ))
			{
				return 1;
			} 	
		}														
	}
	else
	{
		return 1;
	}	   


	for(j=0;j<ParNum;j++)
	{
		sprintf((char*)rbuf,"%02d/%02d",j,ParNum);
		//DisplayString( 0, 0, 88, 4, 0x00, rbuf, 0 );
		if( AH_Comm_8583_PubKeyParDownLoad( send_buf, &send_size, &buf[j][0], buf[j][16], 1 ) != 0 )			//下载公钥
			goto END;
	
		for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
		{
			OS_SleepMs(1000);
			rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );	//发送数据
			if( rcode != 0 )											//发送数据
			{ 
				UP_Com_Count[6]++;
				DEF_UPCash_Debug; 
				return rcode; 
			}
			UP_Com_Count[7]++;
			rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
	        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
			{ 
				UP_Com_Count[4]++;
				DEF_UPCash_Debug; 
				return rcode; 
			}
			UP_Com_Count[5]++;

			rcode = APP_8583_DealSta( rev_buf[9]&0x0f );
			if( rcode != 0 )
				continue;		
			if((rev_buf[13] !=0x08 )||(rev_buf[14] !=0x10 ))
				continue;
			rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size);
			if( rcode != 0 )
				continue;
			if((rev_buf[Information8583SetRcv[38].Seat] !=0x30 )||(rev_buf[Information8583SetRcv[38].Seat+1] !=0x30 ))
			{	
				memset(rbuf, 0, 5);
				CurCalc_ASCII_Proc( 2, &rev_buf[Information8583SetRcv[38].Seat], 2, rbuf, 0 );
			    APP_UPCash_DisTF_Server_Error( rbuf[0], 5 );								 
				goto END;
			}
			
			if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], &send_buf[23], 8) != 0 )
				continue;
			if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], &send_buf[31], 15) != 0 )
				continue;
			if(rev_buf[Information8583SetRcv[61].Seat] ==0x30)
				continue;
			memset(rbuf, 0, 5);
			sprintf((char*)rbuf,"%02X%02X", rev_buf[Information8583SetRcv[61].Seat-2], rev_buf[Information8583SetRcv[61].Seat-1]);
			rev_size = atoi((const char*)rbuf)-1;
			if(rev_size>500)
			{return 1;}
			rcode = UP_ICParTLV_AnalysisCheckAndSave(&rev_buf[Information8583SetRcv[61].Seat+1], rev_size);
			if( rcode != 0 )
				return rcode;	
//			UpdateDayAndTime(&rev_buf[Information8583SetRcv[11].Seat],&rev_buf[Information8583SetRcv[12].Seat],rev_buf);
			break;														//发送成功	
		}
		if( i >= UP_UPCash_Com_ErrMaxNum )								//发送失败
			goto END;
	}
//	sprintf((char*)rbuf,"%02d/%02d",j,ParNum);
//	DisplayString( 0, 0, 88, 4, 0x00, rbuf, 0 );
	UP_SysCfg.CAPKeyAndICParmSta &= ~2;
	UP_Save_ECSysCfg();
	return 0;
	END:
	return 17;
}
U08 APP_Comm_8583_ParDownLoadOver(void)
{
	U32 rcode, i;
	U08 send_buf[200],rbuf[5];
	U32 send_size;
	U08 rev_buf[750];
	U32 rev_size;
	
	__8583Information  Information8583SetRcv[64];
	if( AH_Comm_8583_PubKeyParDownLoadOver( send_buf, &send_size, 1 ) != 0 )			//下载公钥结束
		return 3; 
	for(i = 0; i < UP_UPCash_Com_ErrMaxNum; i++ )					//如果发送失败，可以重复发送
	{
		OS_SleepMs(1000);
		rcode = Com_Dev_TxData( send_buf, send_size, UP_Comm_Config.WiComTxTimeOut, 1 );	//发送数据
		if( rcode != 0 )											//发送数据
		{ 
			UP_Com_Count[6]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[7]++;
		rcode = Com_Dev_RxData( rev_buf, &rev_size, sizeof(rev_buf), UP_Comm_Config.WiComRxTimeOut, 1 ); 
        if( rcode != 0 )                                     		//接收数据                                                                                                                                                                       		if( rcode != 0 )
		{ 
			UP_Com_Count[4]++;
			DEF_UPCash_Debug; 
			return rcode; 
		}
		UP_Com_Count[5]++;

		rcode = APP_8583_DealSta( rev_buf[9]&0x0f );
		if( rcode != 0 )
			continue;		
		if((rev_buf[13] !=0x08 )||(rev_buf[14] !=0x10 ))
			continue;
		rcode = APP_8583_Analysis( Information8583SetRcv, rev_buf+15, rev_buf, rev_size);
		if( rcode != 0 )
			continue;
		if((rev_buf[Information8583SetRcv[38].Seat] !=0x30 )||(rev_buf[Information8583SetRcv[38].Seat+1] !=0x30 ))
		{	
			memset(rbuf, 0, 5);
			CurCalc_ASCII_Proc( 2, &rev_buf[Information8583SetRcv[38].Seat], 2, rbuf, 0 );
		    APP_UPCash_DisTF_Server_Error( rbuf[0], 5 );
			return 17; 
		}
		
		if(memcmp(&rev_buf[Information8583SetRcv[40].Seat], &send_buf[23], 8) != 0 )
			continue;
		if(memcmp(&rev_buf[Information8583SetRcv[41].Seat], &send_buf[31], 15) != 0 )
			continue;
//		UpdateDayAndTime(&rev_buf[Information8583SetRcv[11].Seat],&rev_buf[Information8583SetRcv[12].Seat],rev_buf);
		break;														//发送成功	
	}
	if( i >= UP_UPCash_Com_ErrMaxNum )								//发送失败
		return 3; 

	return 0;
}

/*
**************************************************************************************************************
*Iso8583 IC卡参数下载
**************************************************************************************************************
*/
U32 APP_8583_ParDownLoad( void )
{
	U32 rcode;
	U08 ParNum=0;
	U08 buf[16][17]={0};
	
	rcode = APP_Comm_8583_ParStaUpLoad(buf,&ParNum);		 //状态上送
	if(rcode)
	{
		return rcode;
	}
	rcode = APP_Comm_8583_ParDownLoad(buf,ParNum);			//IC卡参数下载
	if(rcode)
	{
		return rcode;
	}
	rcode = APP_Comm_8583_ParDownLoadOver();			    //下载结束
	if(rcode)
	{
		return rcode;
	}

	return 0;
}

/*
**************************************************************************************************************
* 处理处理要求
**************************************************************************************************************
*/
U32 APP_8583_DealSta( U08 DealSta )
{
	switch( DealSta ) 
	{
    	case 0:
        	break;	
		case 3:
			UP_SysCfg.QDState = 0;
	  		UP_Save_ECSysCfg();
        	return 3;
		case 4:
			UP_SysCfg.CAPKeyAndICParmSta |= 3;
			UP_Save_ECSysCfg();
        	return 0;
		case 5:
        	break;
		case 6:
        	break;
		default:
			break;
	}
	return 0;
}



